package com.ruoyi.utils;

import com.ruoyi.base.domain.BaseLottery;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.config.ApplicationContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
@Component
public class LotteryUtil {

    private static final String LETTERS = "ABCDEF";
    private static final String DIGITS = "023456789";
    private static final String LETTERS_DIGITS = "ABCDEF023456789";
    private static final String IMAGE_NUM = "image_num";

    private static RedisCache redisCache;

    public LotteryUtil() {
        this.redisCache = ApplicationContextHolder.getBean(RedisCache.class);
    }


    public static List<String> botteryOne() {

        List<String> list = new LinkedList<>();

        for (int i = 0; i <= 9; i++) {
            for (int j = 0; j <= 9; j++) {
                for (int k = 0; k <= 9; k++) {
                    BaseLottery lottery = new BaseLottery();
                    // 格式化数字为三位字符串，不足的前面补0
                    String combination = String.format("%d%d%d", i, j, k);
                    list.add(combination);
                }
            }
        }
        return list;
    }

    public static List<String> botteryThree() {

        List<String> list = new LinkedList<>();

        for (int firstTwo = 0; firstTwo <= 8; firstTwo++) {
            for (int third = firstTwo + 1; third <= 9; third++) {
                String combination = String.format("%d%d%d", firstTwo, firstTwo, third);
                list.add(combination);
                //System.out.println(combination);
            }
        }

        for (int first = 0; first <= 8; first++) {
            for (int lastTwo = first + 1; lastTwo <= 9; lastTwo++) {
                String combination = String.format("%d%d%d", first, lastTwo, lastTwo);
                list.add(combination);
                //System.out.println(combination);
            }
        }
        return list;
    }

    public static List<String> botterySix() {

        List<String> list = new LinkedList<>();

        for (int i = 0; i <= 7; i++) {          // 第一个数字从0到7
            for (int j = i + 1; j <= 8; j++) {  // 第二个数字大于第一个数字
                for (int k = j + 1; k <= 9; k++) { // 第三个数字大于第二个数字
                    String combination = String.format("%d%d%d", i, j, k);
                    list.add(combination);
                }
            }
        }
        return list;
    }

    public static Set<String> threeCombinations(String digits) {
        Set<String> result = new TreeSet<>();
        char[] digitArray = digits.toCharArray();

        // 去除重复数字并排序
        Set<Character> uniqueDigits = new TreeSet<>();
        for (char c : digitArray) {
            uniqueDigits.add(c);
        }

        List<Character> sortedDigits = new ArrayList<>(uniqueDigits);

        // 生成 AAB 形式的组合
        for (int i = 0; i < sortedDigits.size(); i++) {
            for (int j = 0; j < sortedDigits.size(); j++) {
                if (i != j) { // 确保A和B不同
                    char a = sortedDigits.get(i);
                    char b = sortedDigits.get(j);
                    if (a <= b) { // 保持有序
                        String combination = "" + a + a + b;
                        result.add(combination);
                    }
                }
            }
        }

        // 生成 ABB 形式的组合
        for (int i = 0; i < sortedDigits.size(); i++) {
            for (int j = 0; j < sortedDigits.size(); j++) {
                if (i != j) { // 确保A和B不同
                    char a = sortedDigits.get(i);
                    char b = sortedDigits.get(j);
                    if (a <= b) { // 保持有序
                        String combination = "" + a + b + b;
                        result.add(combination);
                    }
                }
            }
        }
        return result;
    }

    // 数学公式验证：对于n个不同数字，组合数为 2 * C(n,2)
    public static int calculateExpectedCount(int n) {
        return 2 * (n * (n - 1)) / 2;
    }


    public static Set<String> sixCombinations(String digits) {
        Set<String> result = new TreeSet<>();
        char[] digitArray = digits.toCharArray();
        Arrays.sort(digitArray);
        int n = digitArray.length;

        // 使用三层循环生成所有组合
        for (int i = 0; i < n - 2; i++) {
            for (int j = i + 1; j < n - 1; j++) {
                for (int k = j + 1; k < n; k++) {
                    String combination = "" + digitArray[i] + digitArray[j] + digitArray[k];
                    result.add(combination);
                }
            }
        }
        return result;
    }

    public static Set<String> oneCombinations(String digits) {
        Set<String> result = new TreeSet<>();
        char[] digitArray = digits.toCharArray();
        Arrays.sort(digitArray);
        int n = digitArray.length;

        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (j == i) continue; // 避免重复数字
                for (int k = 0; k < n; k++) {
                    if (k == i || k == j) continue; // 避免重复数字
                    String permutation = "" + digitArray[i] + digitArray[j] + digitArray[k];
                    result.add(permutation);
                }
            }
        }

        return result;
    }

    /**
     * 判断数字是否是对子
     *
     * @param arr
     * @return
     */
    public static Map<String, Long> isAABPatternThree(String[] arr) {
        List<String> list = sortList(arr);

        List<String> newList = new ArrayList<>();

        for (String str : list) {
            // 确保是三位数
            if (str.length() != 3) {
                return null;
            }

            // 检查AAB模式：第一个字符等于第二个字符，但不等于第三个字符
            if (str.charAt(0) == str.charAt(1) && str.charAt(0) != str.charAt(2)) {
                newList.add(str);
            }

            // 检查ABB模式：第一个字符不等于第二个、第三个字符，但第二个字符等于第三个字符
            if (str.charAt(0) < str.charAt(1) && str.charAt(1) == str.charAt(2)) {
                newList.add(str);
            }

        }
        if (newList.size() > 0) {
            String strs = newList.stream().collect(Collectors.joining(","));
            System.out.println("组三：" + strs);
            Map<String, Long> frequency = getAllElementsFrequency(newList);
            return frequency;
        }
        return null;
    }

    public static Map<String, Long> isAABPatternSix(String[] arr) {

        List<String> list = sortList(arr);

        List<String> newList = new ArrayList<>();

        for (String str : list) {
            // 确保是三位数
            if (str.length() != 3) {
                return null;
            }

            // 检查ABC模式
            if (str.charAt(0) < str.charAt(1) && str.charAt(1) < str.charAt(2)) {
                newList.add(str);
            }

        }
        if (newList.size() > 0) {
            String strs = newList.stream().collect(Collectors.joining(","));
            System.out.println("组六：" + strs);
            Map<String, Long> frequency = getAllElementsFrequency(newList);
            return frequency;
        }
        return null;
    }


    public static Map<String, Long> getAllElementsFrequency(List<String> list) {
        if (list == null || list.isEmpty()) {
            return new HashMap<>();
        }
        return list.stream()
                .collect(Collectors.groupingBy(
                        Function.identity(),
                        Collectors.counting()
                ));

    }


    public static List<String> sortList(String[] arr) {
        List<String> numStr = new ArrayList<>();
        for (String str : arr) {
            char[] chars = str.toCharArray();
            // 对字符数组进行排序
            Arrays.sort(chars);

            // 将排序后的字符数组转换回字符串
            String s = new String(chars);
            numStr.add(s);
            //System.out.println(s);
        }
        return numStr;
    }

    public static String digitSort(String numberStr) {

        // 将数字转换为字符串，再转换为字符数组
        char[] digits = numberStr.toCharArray();

        // 对字符数组进行排序
        Arrays.sort(digits);

        // 将排序后的字符数组转换回数字
        String sortedStr = new String(digits);
        //int sortedNumber = Integer.parseInt(sortedStr);

        System.out.println("原数字: " + numberStr);
        System.out.println("排序后: " + sortedStr);

        return sortedStr;
    }

    /**
     * 随机生成4位数字字母组合
     *
     * @param length
     * @return
     */
    public static String generateRandomGroup(int length) {
        StringBuilder group = new StringBuilder();
        for (int i = 0; i < length; i++) {
            int index = ThreadLocalRandom.current().nextInt(LETTERS_DIGITS.length());
            group.append(LETTERS_DIGITS.charAt(index));
        }
        return group.toString();
    }

    /**
     * 随机生成5位数字加字母组合，字母1到2位
     *
     * @return
     */
    public static String generateLimitedGroup() {
        // 随机决定使用1或2个字母
        int letterCount = ThreadLocalRandom.current().nextInt(1, 3); // 1或2
        int digitCount = 5 - letterCount;

        // 生成字母部分
        StringBuilder lettersPart = new StringBuilder();
        for (int i = 0; i < letterCount; i++) {
            int index = ThreadLocalRandom.current().nextInt(LETTERS.length());
            lettersPart.append(LETTERS.charAt(index));
        }

        // 生成数字部分
        StringBuilder digitsPart = new StringBuilder();
        for (int i = 0; i < digitCount; i++) {
            int index = ThreadLocalRandom.current().nextInt(DIGITS.length());
            digitsPart.append(DIGITS.charAt(index));
        }

        // 合并并打乱顺序
        String combined = lettersPart.toString() + digitsPart.toString();
        return shuffleString(combined);
    }

    private static String shuffleString(String input) {
        List<Character> characters = new ArrayList<>();
        for (char c : input.toCharArray()) {
            characters.add(c);
        }
        Collections.shuffle(characters);

        StringBuilder result = new StringBuilder();
        for (char c : characters) {
            result.append(c);
        }
        return result.toString();
    }

    public static String generateStrNum() {
        try {
            List<String> listStr = new ArrayList<>();
            for (int i = 0; i < 5; i++) {
                listStr.add(generateRandomGroup(4));
            }

            String str5 = listStr.stream().collect(Collectors.joining("-"));
            log.info("str5:" + str5);

            /*StringBuilder sb = new StringBuilder();
            for (int i = 0; i < 8; i++) {
                sb.append(ThreadLocalRandom.current().nextInt(10));
            }*/

            String lastNum = str5 + "/" + PropertiesDailyGenerator.getDailyNumber() + "/" + generateLimitedGroup();

            //String lastNum = str5 + "/" + sb.toString() + "/" +generateLimitedGroup();

            log.info(lastNum);
            return lastNum;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    public static int getImageNum() {
        try {
            /*Random random = new Random();
            int randNum = random.nextInt(13) + 1;*/
            int randNum = 0;
            int imageNum = 20;
            if (redisCache.hasKey("imgNum")) {
                randNum = redisCache.getCacheObject("imgNum");
            }
            Properties props = PropertiesDailyGenerator.loadProperties();
            if (props != null) {
                imageNum = Integer.valueOf(props.getProperty(IMAGE_NUM)) + 1;
            }

            randNum = randNum + 1;
            if (randNum >= imageNum) {
                randNum = 1;
            }
            redisCache.setCacheObject("imgNum", randNum);

            //System.out.println("获取的图片：" + randNum + ".png");
            log.info("获取的图片：" + randNum + ".png");
            return randNum;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 1;
    }

    public static void main(String[] args) {

        //generateStrNum();
        //digitSort("322");

        System.out.println("随机生成的4字符组:");
        for (int i = 0; i < 20; i++) {
            System.out.println(getImageNum());
        }

        //System.out.println(generateLimitedGroup());
    }
}
